package heap

import "JVM/Jvmgo/GoToJVM/classfile"

type MethodRef struct {
	MemberRef
	method *Method
}

func newMethodRef(cp *ConstantPool, refInfo *classfile.ConstantMethodrefInfo) *MethodRef {
	ref := &MethodRef{}
	ref.cp = cp
	ref.copyMemberRefInfo(&refInfo.ConstantMemberrefInfo)
	return ref
}

// 如果解析过符号引用就直接返回，没解析过调用 resolveMethod 函数进行解析
func (self *MethodRef) ResolvedMethod() *Method {
	if self.method == nil {
		self.resolveMethod()
	}
	return self.method
}

func (self *MethodRef) resolveMethod() {
	d := self.cp.class
	c := self.ResolvedClass()
	if c.IsInterface() {
		panic("java.lang.incompatibleClassChangeError")
	}

	method := lookupMethod(c, self.name, self.descriptor)
	if method == nil {
		panic("java.lang.NoSuchMethodError")
	}
	if !method.isAccessibleTo(d) {
		panic("java.lang.IllegalAccessError")
	}

	self.method = method
}

func lookupMethod(class *Class, name, descriptor string) *Method {
	method := LookupMethodInClass(class, name, descriptor)
	if method == nil {
		method = lookupMethodInInterface(class.interfaces, name, descriptor)
	}
	return method
}

// getter
func (self *MethodRef) Name() string {
	return self.name
}
func (self *MethodRef) Descriptor() string {
	return self.descriptor
}
